package org.dromara.bean.util;

import cn.hutool.core.util.ObjectUtil;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.dromara.bean.constant.BusinessCodeTypeConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * 生成订单号工具类
 **/
@Service
public class BusinessCodeUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * * 前缀：固定字母缩写大写，比如PH。一般是表名缩写
     * *
     * * 业务类型：根据业务需求，设置业务类型，比如01。
     * *
     * * 时间戳：使用当前的日期和时间作为用户编号的一部分，精确到小时级别，并按照指定的格式进行格式化，例如"yyyyMMddHH"。
     * *
     * * 自增数：生成自增序号 5位数
     * * 前缀和业务类型时间戳用-分割
     * * 前缀统一维护到 org.jeecg.common.constant.BusinessCodeTypeConstant
     * 示例最终结果：SU-01-20231004-000002
     *
     * @param prefix
     * @param businessType
     * @return
     */
    public String genCode(String prefix, Integer businessType) {
        StringBuilder number = new StringBuilder();
        // Add prefix 一般都是表名缩写大写词 这里支持传入下划线隔开的字符串
        if (prefix != null) {
            if (!prefix.contains("_")) {
                number.append(prefix.toUpperCase());
            } else {
                String[] words = prefix.split("_");
                StringBuilder result = new StringBuilder();
                for (String word : words) {
                    if (!word.isEmpty()) {
                        char firstChar = Character.toUpperCase(word.charAt(0));
                        result.append(firstChar);
                    }
                }
                number.append(result);
            }
            number.append("-");
        }

        // Add business type 例如用户角色，订单类型，默认的是01 不够1位填充0
        if (ObjectUtil.isNotEmpty(businessType)) {
            String businessTypeString = String.format("%02d", businessType);
            number.append(businessTypeString);
            number.append("-");
        }

        // Add timestamp
        LocalDateTime now = LocalDateTime.now();
        String currentDate = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        number.append(currentDate);
        RedisAtomicLong entityIdCounter;
        try {
            // 注意这里的键值是最新的number字符串
            entityIdCounter = new RedisAtomicLong(number.toString(), redisTemplate.getConnectionFactory());
        } catch (Exception e) {
            throw new RuntimeException("生成序列号失败" + e);
        }
        long incrementId = entityIdCounter.getAndIncrement() + 1;
        if (incrementId == 1) {
            entityIdCounter.expire(48, TimeUnit.HOURS);
        }
        number.append("-");
        // Add increment number 6位数，不够6位填充0
        String incrementNumberString = String.format("%05d", incrementId);
        number.append(incrementNumberString);

        return number.toString();
    }

    /**
     * 只用前缀就能解决的
     * @param prefix
     * @return
     */
    public String genCode(String prefix) {
        return this.genCode(prefix, null);
    }
}
